package data

import (
	"GoSecKill/conf"
	"github.com/go-redis/redis/v7"
)

var client *redis.Client

// 开启redis连接池
func initRedisConnection(config conf.AppConfig)  {
	client = redis.NewClient(&redis.Options{
		Addr:     config.App.Redis.Address,
		Password: config.App.Redis.Password, // It's ok if password is "".
		DB:       0,  // use default DB
	})

	if _, err := FlushAll(); err != nil {
		println("Error when flushAll. " + err.Error())
	}
}

// 用于测试
func FlushAll() (string, error) {
	// flushall 命令会清空redis所有的库
	// 本地调试可以，但是生产环境中需要谨慎，确保值清除对应的库
	return client.FlushAll().Result()
}

// 确保redis加载lua脚本，若未加载则加载
func PrepareScript(script string) string {
	// sha := sha1.Sum([]byte(script))
	// 用于校验指定的脚本是否已经被保存在缓存当中。
	scriptsExists, err := client.ScriptExists(script).Result()
	if err != nil {
		panic("Failed to check if script exists: " + err.Error())
	}
	if !scriptsExists[0] {
		// 加载脚本  根据脚本名称
		scriptSHA, err := client.ScriptLoad(script).Result()
		if err != nil {
			panic("Failed to load script " + script + " err: " + err.Error())
		}
		return scriptSHA
	}
	print("Script Exists.")
	return ""
}

// 执行lua脚本
func EvalSHA(sha string, args []string) (interface{}, error) {
	val, err := client.EvalSha(sha, args).Result()
	if err != nil {
		print("Error executing evalSHA... " + err.Error())
		return nil, err
	}
	return val, nil
}

// redis operation SET
func SetForever(key string, value interface{}) (string, error) {
	val, err := client.Set(key, value, 0).Result()  // expiration表示无过期时间
	return val, err
}

// redis operation hmset
// func SetMapForever(key string, field map[string]interface{}) (int64, error) {
// 	return client.HSet(key, field).Result()
// 	// return client.HMSet(key, field).Result()
// }

// hmset
func SetMapForever(key string, field map[string]interface{}) (bool,error) {
	return client.HMSet(key,field).Result()
}

// redis operation hmget
func GetMap(key string, fields ...string) ([]interface{}, error) {
	return client.HMGet(key, fields...).Result()
}

// redis SADD
func SetAdd(key string, field string) (int64, error) {
	// 集合Set SADD
	return client.SAdd(key, field).Result()
}

// redis SISMEMBER 判断field是否是集合key的成员
func SetIsMember(key string, field string) (bool, error) {
	// SISMEMBER key member 判断member是否是集合key的成员
	return client.SIsMember(key, field).Result()
}

// redis SMEMBERS  返回集合中所有成员
func GetSetMembers(key string) ([]string, error) {
	return client.SMembers(key).Result()
}